from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from oauth2client.client import OAuth2WebServerFlow, FlowExchangeError
import logging
import pickle
import settings


def oauth_redirect(request, redirect=None):
    """ Redirects to the oauth sign in page using the oauth 2 client code to create a
    OAuth2WebServerFlow object.

    Requires OAUTH_SETTINGS are set within settings.py
        
    The flow object can create an authorize_url to redirect to OAuth.
    """
    
    # If not already authenticated with then redirect to sign link
    if 'credentials' not in request.session:
        
        # Store redirect in session for OAuth callback
        request.session['redirect']=redirect
        
        flow = OAuth2WebServerFlow(
          # Visit https://code.google.com/apis/console to
          # generate your client_id, client_secret and to
          # register your redirect_uri.
          client_id=settings.OAUTH_SETTINGS['client_id'],
          client_secret=settings.OAUTH_SETTINGS['client_secret'],
          scope=settings.OAUTH_SETTINGS['scope'],
          user_agent=settings.OAUTH_SETTINGS['user_agent'],
          approval_prompt='force')
        
        # Generate the URL to OAuth with passing the redirect URI
        authorize_url = flow.step1_get_authorize_url(settings.OAUTH_SETTINGS['redirect_uri'])
        
        request.session['flow']=pickle.dumps(flow)
        return HttpResponseRedirect(authorize_url)
    
    return render_to_response("auth-redirect.html", {"redirect": reverse(redirect)},
        context_instance=RequestContext(request))

def oauth_callback(request):
    """ Page shown to people who've returned from OAuth.

        Users are redirected here by Google after allowing/denying OAuth access with an OAuth 2
        authorization code or an error. The GET params must have a auth code and the session must
        have an OAuth2WebServerFlow object with the flow. Then the credentials can be retrieved
        and put into the session

    """
    
    if 'flow' in request.session and 'code' in request.GET:
        try:
            flow = pickle.loads(request.session['flow'])
            credentials = flow.step2_exchange(request.GET)
            request.session['credentials'] = credentials
            redirect = 'redirect' in request.session and request.session['redirect'] or settings.OAUTH_DEFAULT_REDIRECT
            return render_to_response("auth-redirect.html", {"redirect": reverse(redirect)},
                context_instance=RequestContext(request))
        
        except FlowExchangeError:
            logging.exception('Failed to authenticate')

    return HttpResponseRedirect(reverse(settings.OAUTH_FAILED_REDIRECT))


def oauth_logout(request, redirect=None):
    """ Logout the OAuth session, removing the access token from the session"""
    clear_oauth_session(request)
    return HttpResponseRedirect(reverse(redirect))

      
def clear_oauth_session(request):
    """ Clears the session of all OAuth related data """
    for key in settings.OAUTH_SESSION_KEYS:              
        if key in request.session:
            del request.session[key]
                    
                    
    
